﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.LinkLabel;

namespace Znice
{
    public class DefaultFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
        }
    }

    /// <summary>
    /// 加粗
    /// </summary>
    public class BoldFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            Font oldFont = richTextBox.SelectionFont;
            oldFont ??= richTextBox.Font;
            Font newFont;
            if (oldFont.Bold)
            {
                newFont = new Font(oldFont, oldFont.Style & ~FontStyle.Bold);//支持位于运算
            }
            else
            {
                newFont = new Font(oldFont, oldFont.Style | FontStyle.Bold);
            }
            richTextBox.SelectionFont = newFont;

        }
    }

    /// <summary>
    /// 斜体
    /// </summary>
    public class ItalicFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            Font oldFont = richTextBox.SelectionFont;
            oldFont ??= richTextBox.Font;
            Font newFont;
            if (oldFont.Italic)
            {
                newFont = new Font(oldFont, oldFont.Style & ~FontStyle.Italic);
            }
            else
            {
                newFont = new Font(oldFont, oldFont.Style | FontStyle.Italic);
            }
            richTextBox.SelectionFont = newFont;
            richTextBox.Focus();

        }
    }

    /// <summary>
    /// 下划线
    /// </summary>
    public class UnderLineFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            Font oldFont = richTextBox.SelectionFont;
            oldFont ??= richTextBox.Font;
            Font newFont;
            if (oldFont.Underline)
            {
                newFont = new Font(oldFont, oldFont.Style & ~FontStyle.Underline);
            }
            else
            {
                newFont = new Font(oldFont, oldFont.Style | FontStyle.Underline);
            }
            richTextBox.SelectionFont = newFont;
            richTextBox.Focus();

        }
    }

    /// <summary>
    /// 删除线
    /// </summary>
    public class StrikeThroughFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            Font oldFont = richTextBox.SelectionFont;
            oldFont ??= richTextBox.Font;
            Font newFont;
            if (oldFont.Underline)
            {
                newFont = new Font(oldFont, oldFont.Style & ~FontStyle.Strikeout);
            }
            else
            {
                newFont = new Font(oldFont, oldFont.Style | FontStyle.Strikeout);
            }
            richTextBox.SelectionFont = newFont;
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 左对齐
    /// </summary>
    public class LeftFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            richTextBox.SelectionAlignment = HorizontalAlignment.Left;
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 居中对齐
    /// </summary>
    public class CenterFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            if (richTextBox.SelectionAlignment == HorizontalAlignment.Center)
            {
                richTextBox.SelectionAlignment = HorizontalAlignment.Left;
            }
            else
            {
                richTextBox.SelectionAlignment = HorizontalAlignment.Center;
            }
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 右对齐
    /// </summary>
    public class RightFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            if (richTextBox.SelectionAlignment == HorizontalAlignment.Right)
            {
                richTextBox.SelectionAlignment = HorizontalAlignment.Left;
            }
            else
            {
                richTextBox.SelectionAlignment = HorizontalAlignment.Right;
            }
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 缩进对齐
    /// </summary>
    public class IndentFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            //每次以10个像素进行缩进
            richTextBox.SelectionIndent += 10;
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 向往缩进对齐
    /// </summary>
    public class OutdentFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            //每次以10个像素进行缩进
            richTextBox.SelectionIndent -= 10;
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 下标
    /// </summary>
    public class SubScriptFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            if (richTextBox.SelectionCharOffset < 0)
            {
                richTextBox.SelectionCharOffset = 0;
            }
            else
            {
                richTextBox.SelectionCharOffset = -5;
            }
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 上标
    /// </summary>
    public class SuperScriptFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            if (richTextBox.SelectionCharOffset > 0)
            {
                richTextBox.SelectionCharOffset = 0;
            }
            else
            {
                richTextBox.SelectionCharOffset = 5;
            }
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 字体
    /// </summary>
    public class FontFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            FontDialog f = new()
            {
                ShowColor = true,
                ShowEffects = true
            };
            if (f.ShowDialog() == DialogResult.OK)
            {
                richTextBox.SelectionFont = new Font(f.Font.FontFamily, f.Font.Size, f.Font.Style);
                richTextBox.SelectionColor = f.Color;
            }
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 文本颜色
    /// </summary>
    public class ForeColorFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            ColorDialog f = new();
            if (f.ShowDialog() == DialogResult.OK)
            {
                richTextBox.SelectionColor = f.Color;
            }
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 文本背景颜色
    /// </summary>
    public class BackgroundColorFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            ColorDialog f = new();
            if (f.ShowDialog() == DialogResult.OK)
            {
                richTextBox.SelectionBackColor = f.Color;
            }
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// UL列表,项目符号样式
    /// </summary>
    public class UnorderedListFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            if (richTextBox.SelectionBullet)
            {
                richTextBox.SelectionBullet = false;
            }
            else
            {
                richTextBox.SelectionBullet = true;
                richTextBox.BulletIndent = 10;
            }
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 图片插入
    /// </summary>
    public class PictureFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            OpenFileDialog openFileDialog = new()
            {
                InitialDirectory = AppDomain.CurrentDomain.BaseDirectory,
                Title = "请选择图片",
                Filter = "图片文件|*.gif;*.jpg;*.jpeg;*.bmp;*.jfif;*.png;"
            };
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    Image bmp = Image.FromFile(openFileDialog.FileName);
                    Clipboard.SetDataObject(bmp);

                    DataFormats.Format dataFormat = DataFormats.GetFormat(DataFormats.Bitmap);
                    if (richTextBox.CanPaste(dataFormat))
                    {
                        richTextBox.Paste(dataFormat);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"图片插入失败:{ex.Message}", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 删除
    /// </summary>
    public class DeleteFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            richTextBox.SelectedText = "";
            richTextBox.Focus();
        }
    }

    /// <summary>
    /// 打印
    /// </summary>
    public class PrintFormat : ITextFormat
    {
        // https://learn.microsoft.com/zh-cn/previous-versions/dotnet/articles/ms996492(v=msdn.10)
        public void SetTextFormat(RichTextBox richTextBox)
        {
            int checkPrint = 0;
            PrintDocument pd = new();
            pd.BeginPrint += (sender, e) =>
            {
                checkPrint = 0;
            };
            pd.PrintPage += (sender, e) =>
            {
                checkPrint = RichTextBoxPrint.Print(richTextBox, checkPrint, richTextBox.TextLength, e);
                e.HasMorePages = checkPrint < richTextBox.TextLength;                
            };
            // pd.Print(); // 没有预览，直接打印
            PrintPreviewDialog preview = new()
            {
                Document = pd
            };
            preview.ShowDialog();
        }
    }

    /// <summary>
    /// 减小字体
    /// </summary>
    public class MinusFontSizeFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            Font oldFont = richTextBox.SelectionFont;
            if (oldFont != null)
            {
                float size = oldFont.Size;
                size -= 5;
                if (size < 5)
                {
                    return;
                }
                richTextBox.SelectionFont = new Font(oldFont.FontFamily, size);
                richTextBox.Focus();
            }
        }
    }

    /// <summary>
    /// 增大字体
    /// </summary>
    public class PlusFontSizeFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            Font oldFont = richTextBox.SelectionFont;
            if (oldFont != null)
            {
                float size = oldFont.Size;
                size += 5;
                richTextBox.SelectionFont = new Font(oldFont.FontFamily, size);
                richTextBox.Focus();
            }
        }
    }

    /// <summary>
    /// 撤销
    /// </summary>
    public class UndoFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            richTextBox.Undo();
        }
    }

    /// <summary>
    /// 重做
    /// </summary>
    public class RedoFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            richTextBox.Redo();
        }
    }

    /// <summary>
    /// 插入表格
    /// </summary>
    public class TableFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            FrmTableConfig f = new();
            if (f.ShowDialog() == DialogResult.OK)
            {

                int col = f.columns, row = f.rows;
                StringBuilder rtf = new();
                rtf.Append(@"{\rtf1 ");

                int cellWidth = f.columnWidth * 15;
                if (cellWidth == 0)
                {
                    cellWidth = ((richTextBox.ClientSize.Width - 3) / row) * 15;
                }
                for (int i = 0; i < col; i++)
                {
                    rtf.Append(@"\trowd");
                    for (int j = 1; j <= row; j++)
                        rtf.Append(@"\cellx" + (j * cellWidth).ToString());
                    rtf.Append(@"\intbl \cell \row"); //create row
                }
                rtf.Append(@"\pard");
                rtf.Append('}');
                richTextBox.SelectedRtf = rtf.ToString();//敲重点 SelectedRtf 获取或设置控件中当前选择的 RTF 格式的格式化文本。
            }
        }
    }

    /// <summary>
    /// 打开
    /// </summary>
    public class OpenFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            OpenFileDialog openFileDialog = new()
            {
                Filter = "*.rtf|*.rtf"
            };
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                richTextBox.LoadFile(openFileDialog.FileName, RichTextBoxStreamType.RichText);
            }
        }
    }

    /// <summary>
    /// 另存为
    /// </summary>
    public class SaveAsFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            SaveFileDialog saveFileDialog = new()
            {
                DefaultExt = "*.rtf",
                Filter = "RTF Files|*.rtf"
            };
            if (saveFileDialog.ShowDialog() == DialogResult.OK && saveFileDialog.FileName.Length > 0)
            {
                richTextBox.SaveFile(saveFileDialog.FileName, RichTextBoxStreamType.RichText);
            }
        }
    }

    /// <summary>
    /// 链接
    /// </summary>
    public class LinkFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            if (!string.IsNullOrEmpty(richTextBox.SelectedText))
            {
                FrmLink f = new();
                if (f.ShowDialog() == DialogResult.OK)
                {
                    RichTextBoxLink link = new(richTextBox);
                    string? url = f.Tag?.ToString();
                    if (url != null)
                    {
                        string selectedText = richTextBox.SelectedText;
                        richTextBox.SelectedText = "";
                        link.InsertLink(selectedText, url);
                    }
                    /* 注释的原因是 .net6下，e.LinkText 只会返回text,不能返回 hyperlink */
                    //richTextBox.LinkClicked += (sender, e) =>
                    //{
                    //    //  Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
                    //    MessageBox.Show("A link has been clicked.\nThe link text is '" + e.LinkText + "'");
                    //    MessageBox.Show(richTextBox.Text);
                    //};
                }
            }
            else
            {
                MessageBox.Show("请先选择链接文本");
            }
        }
    }

    public class UnLinkFormat : ITextFormat
    {
        public void SetTextFormat(RichTextBox richTextBox)
        {
            string selectedText = richTextBox.SelectedText;
            richTextBox.SelectedText = "";
        }
    }
}
